package org.minos.edit.controller.manager
{
	import flash.events.Event;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.FileFilter;
	import flash.utils.Dictionary;
	
	/**
	 * ...
	 * @author Minos
	 */
	public class FileManager
	{
		public static const NAME : String = "FileManager"
		public static const OPEN : String = NAME + "_Open";
		public static const SAVE : String = NAME + "_Save";
		public static const BROWSE_FOR_DIRECTORY : String = NAME + "_BrowseForDirectory";
		public static const BROWSE_FOR_OPEN : String = NAME + "_BrowseForOpen";
		public static const BROWSE_FOR_SAVE : String = NAME + "_BrowseForSave";
		
		private static var _rootFile : File;
		private static var _currentFile : File;
		private static var _callBack : Function;
		private static var files : Dictionary = new Dictionary();
		
		public function FileManager()
		{
		}
		
		/**
		 *
		 */
		public static function clear() : void
		{
			files = new Dictionary();
		}
		
		/**
		 *
		 * @param	name
		 * @param	path
		 * @param	isNew
		 * @return
		 */
		public static function getFile( name : String , path : String = null , isNew : Boolean = false ) : File
		{
			if ( files[ name ] == null || isNew )
				files[ name ] = new File( path );
			return files[ name ];
		}
		
		/**
		 *
		 * @param	name
		 */
		public static function delFile( name : String ) : void
		{
			files[ name ] = null;
		}
		
		private static function active( _file : Object , data : Object ) : void
		{
			var file : File;
			if ( _file != null && ( _file is File ) )
				file = ( _file as File )
			else
				file = checkFile( _file as String );
			setCallBack( data.callBack );
			switch ( data.type )
			{
				case BROWSE_FOR_DIRECTORY: 
					file.browseForDirectory( data.title );
					break;
				case BROWSE_FOR_OPEN: 
					file.browseForOpen( data.title , data.typeFilter );
					break;
				case BROWSE_FOR_SAVE: 
					file.browseForSave( data.title );
					break;
				case SAVE: 
					writeUTFBytes( file , data.content )
					return;
					break;
				default: 
			}
			file.addEventListener( Event.SELECT , __slectedHandler );
		}
		
		/**
		 *
		 * @param	name
		 * @param	callBack
		 * @param	title
		 */
		public static function browseForDirectory( name : Object = null , callBack : Function = null , title : String = "目录" ) : void
		{
			active( name , { type: BROWSE_FOR_DIRECTORY , callBack: callBack , title: title } );
		}
		
		/**
		 *
		 * @param	name
		 * @param	callBack
		 * @param	title
		 * @param	typeFilter
		 */
		public static function browseForOpen( name : Object = null , callBack : Function = null , title : String = "打开" , typeFilter : Array = null ) : void
		{
			active( name , { type: BROWSE_FOR_OPEN , callBack: callBack , title: title , typeFilter: typeFilter } );
		}
		
		/**
		 * 保存
		 * @param	content
		 * @param	file
		 */
		public static function save( name : Object = null , callBack : Function = null , content : Object = "" ) : void
		{
			try
			{
				//writeUTFBytes( checkFile( name ) , content );
				active( name , { type: SAVE , content: content } );
			}
			catch ( e : Error )
			{
				saveAs( name , callBack , "保存到" , content );
			}
		}
		
		/**
		 * 保存到
		 * @param	content
		 * @param	file
		 */
		public static function saveAs( name : Object = null , callBack : Function = null , title : String = "保存到" , content : Object = "" ) : void
		{
			active( name , { type: BROWSE_FOR_SAVE , callBack: callBack , title: title , content: content } );
		}
		
		/**
		 * 写入文件
		 * @param	file
		 * @param	content
		 */
		public static function writeUTFBytes( file : File , content : Object ) : void
		{
			var stream : FileStream = new FileStream();
			stream.open( file , FileMode.WRITE );
			stream.writeUTFBytes( content.replace( /\n/g , File.lineEnding ) );
			stream.close();
		}
		
		/**
		 * 读取文件
		 * @param	file
		 * @return
		 */
		public static function readUTFBytes( file : File ) : Object
		{
			var fileStream : FileStream;
			var obj : Object;
			if ( file )
			{
				try
				{
					fileStream = new FileStream();
					fileStream.open( file , FileMode.READ );
					obj = fileStream.readUTFBytes( fileStream.bytesAvailable );
					fileStream.close();
					return obj;
				}
				catch ( e : Error )
				{
				}
			}
			
			return null;
		}
		
		// ----- get & set ----- //
		
		/**
		 * get current file
		 * @return
		 */
		public static function getCurrentFile() : File
		{
			return _currentFile;
		}
		
		public static function setCurrentFile( f : File ) : void
		{
			_currentFile = f;
		}
		
		/**
		 * get callback function
		 * @return
		 */
		public static function getCallBack() : Function
		{
			return _callBack;
		}
		
		public static function setCallBack( f : Function ) : void
		{
			_callBack = f;
		}
		
		/**
		 * get root file
		 * @return
		 */
		public static function getRootFile() : File
		{
			return _rootFile;
		}
		
		public static function setRootFile( f : File ) : void
		{
			_rootFile = f;
		}
		
		/**
		 *
		 * @param	file
		 * @return
		 */
		private static function checkFile( name : String = null ) : File
		{
			return name ? getFile( name ) : _currentFile ? _currentFile : getFile( "def" );
		}
		
		// ----- event methods ----- //
		
		/**
		 *
		 * @param	e
		 */
		private static function __slectedHandler( e : Event ) : void
		{
			if ( _callBack != null )
			{
				_callBack( e.target );
				_callBack = null;
			}
			File( e.target ).removeEventListener( Event.SELECT , __slectedHandler );
		}
	
	}

}